#ifndef __M_QUEUE_H__
#define __M_QUEUE_H__

/**
 * @file queue.hpp
 * @brief 队列管理模块
 * 
 * 本模块实现队列的声明、删除、持久化存储及内存管理功能。
 * 包含三个核心组件：
 * 1. MsgQueue - 队列数据结构
 * 2. MsgQueueMapper - 数据库持久化管理
 * 3. MsgQueueManager - 内存管理及线程安全操作
 */

#include "../common/logger.hpp"    // 日志记录功能
#include "../common/helper.hpp"    // 辅助工具（字符串/文件处理）
#include "../common/msg.pb.h"      // Protobuf 消息定义
#include <iostream>
#include <unordered_map>                // 哈希表实现
#include <mutex>                        // 互斥锁
#include <memory>                       // 智能指针

namespace bitmq 
{
    /**
     * @struct MsgQueue
     * @brief 消息队列数据结构，表示单个消息队列的属性和配置
     * 
     * 包含队列的基本属性（名称、持久化标志等）和自定义参数，
     * 提供参数的序列化和反序列化功能。
     */
    struct MsgQueue 
    {
        using ptr = std::shared_ptr<MsgQueue>;  ///< 队列智能指针类型别名
        
        // 队列属性
        std::string name;                         ///< 队列唯一标识名称
        bool durable;                             ///< 持久化标志（true=持久化存储）
        bool exclusive;                           ///< 排他队列标志（true=仅创建者连接可用）
        bool auto_delete;                         ///< 自动删除标志（true=无消费者时自动删除）
        google::protobuf::Map<std::string, std::string> args;  ///< 自定义参数键值对
        
        /**
         * @brief 默认构造函数
         */
        MsgQueue() {} 
        
        /**
         * @brief 参数化构造函数
         * @param qname 队列名称
         * @param qdurable 持久化标志
         * @param qexclusive 排他队列标志
         * @param qauto_delete 自动删除标志
         * @param qargs 自定义参数键值对
         */
        MsgQueue(const std::string &qname, 
                bool qdurable, 
                bool qexclusive,
                bool qauto_delete,
                const google::protobuf::Map<std::string, std::string> &qargs)
            : name(qname), 
              durable(qdurable), 
              exclusive(qexclusive),
              auto_delete(qauto_delete), 
              args(qargs) {}
        
        /**
         * @brief 从字符串解析队列参数
         * @param str_args 参数字符串（格式：k1=v1&k2=v2）
         * 
         * 将形如 "key1=value1&key2=value2" 的字符串解析为键值对参数
         */
        void setArgs(const std::string &str_args) 
        {
            std::vector<std::string> sub_args;
            StrHelper::split(str_args, "&", sub_args);
            for (auto &str : sub_args) 
            {
                size_t pos = str.find("=");
                if (pos == std::string::npos) continue;
                std::string key = str.substr(0, pos);
                std::string val = str.substr(pos + 1);
                args[key] = val;
            }
        }
        
        /**
         * @brief 序列化队列参数为字符串
         * @return 参数字符串（格式：k1=v1&k2=v2）
         */
        std::string getArgs() 
        {
            std::string result;
            for (auto start = args.begin(); start != args.end(); ++start) 
            {
                result += start->first + "=" + start->second + "&";
            }
            return result;
        }
    };
    
    using QueueMap = std::unordered_map<std::string, MsgQueue::ptr>; ///< 队列映射类型（名称->队列指针）
    
    /**
     * @class MsgQueueMapper
     * @brief 消息队列持久化管理器，负责队列数据的SQLite数据库操作
     * 
     * 提供队列信息的存储、删除和恢复功能，实现队列状态的持久化。
     */
    class MsgQueueMapper 
    {
    public:
        /**
         * @brief 构造函数
         * @param dbfile SQLite数据库文件路径
         */
        MsgQueueMapper(const std::string &dbfile)
            : _sql_helper(dbfile) 
            {
            std::string path = FileHelper::parentDirectory(dbfile);
            FileHelper::createDirectory(path);
            _sql_helper.open();
            createTable();
        }
        
        /**
         * @brief 创建队列存储表
         * 
         * 在数据库中创建 queue_table 表用于存储队列信息，表结构：
         * - name: VARCHAR(32) PRIMARY KEY
         * - durable: INT
         * - exclusive: INT
         * - auto_delete: INT
         * - args: VARCHAR(128)
         */
        void createTable() 
        {
            std::stringstream sql;
            sql << "CREATE TABLE IF NOT EXISTS queue_table(";
            sql << "name VARCHAR(32) PRIMARY KEY, ";
            sql << "durable INT, ";
            sql << "exclusive INT, ";
            sql << "auto_delete INT, ";
            sql << "args VARCHAR(128));";
            assert(_sql_helper.exec(sql.str(), nullptr, nullptr));
        }
        
        /**
         * @brief 删除队列存储表（仅用于清理）
         */
        void removeTable() 
        {
            std::string sql = "DROP TABLE IF EXISTS queue_table;";
            _sql_helper.exec(sql, nullptr, nullptr);
        }
        
        /**
         * @brief 插入队列记录到数据库
         * @param queue 队列智能指针
         * @return 操作是否成功
         */
        bool insert(MsgQueue::ptr &queue) {
            std::stringstream sql;
            sql << "INSERT INTO queue_table VALUES(";
            sql << "'" << queue->name << "', ";
            sql << queue->durable << ", ";
            sql << queue->exclusive << ", ";
            sql << queue->auto_delete << ", ";
            sql << "'" << queue->getArgs() << "');";
            return _sql_helper.exec(sql.str(), nullptr, nullptr);
        }
        
        /**
         * @brief 从数据库删除指定队列记录
         * @param name 要删除的队列名称
         */
        void remove(const std::string &name)
        {
            std::stringstream sql;
            sql << "DELETE FROM queue_table WHERE name='";
            sql << name << "';";
            _sql_helper.exec(sql.str(), nullptr, nullptr);
        }
        
        /**
         * @brief 从数据库恢复所有队列
         * @return 包含所有持久化队列的映射表
         */
        QueueMap recovery() 
        {
            QueueMap result;
            std::string sql = "SELECT name, durable, exclusive, auto_delete, args FROM queue_table;";
            _sql_helper.exec(sql, selectCallback, &result);
            return result;
        }
        
    private:
        /**
         * @brief SQL查询结果回调函数（内部使用）
         * @param arg 用户数据指针（此处为QueueMap*）
         * @param numcol 返回的列数
         * @param row 行数据数组
         * @param fields 列名数组
         * @return 操作状态码（0=成功）
         */
        static int selectCallback(void* arg, int numcol, char** row, char** fields) 
        {
            QueueMap *result = static_cast<QueueMap*>(arg);
            MsgQueue::ptr mqp = std::make_shared<MsgQueue>();
            
            mqp->name = row[0];
            mqp->durable = std::stoi(row[1]);
            mqp->exclusive = std::stoi(row[2]);
            mqp->auto_delete = std::stoi(row[3]);
            
            if (row[4] != nullptr) 
            {
                mqp->setArgs(row[4]);
            }
            
            result->insert(std::make_pair(mqp->name, mqp));
            return 0;
        }
        
    private:
        SqliteHelper _sql_helper;  ///< SQLite 数据库操作助手
    };

    /**
     * @class MsgQueueManager
     * @brief 消息队列管理器，集成内存和持久化存储
     * 
     * 提供线程安全的队列声明、删除和查询功能，
     * 自动处理持久化队列的数据库同步。
     */
    class MsgQueueManager 
    {
    public:
        using ptr = std::shared_ptr<MsgQueueManager>;  ///< 管理器智能指针类型别名
        
        /**
         * @brief 构造函数
         * @param dbfile SQLite数据库文件路径
         */
        MsgQueueManager(const std::string &dbfile)
            : _mapper(dbfile) {
            _msg_queues = _mapper.recovery();
        }
        
        /**
         * @brief 声明/创建新队列
         * @param qname 队列名称
         * @param qdurable 持久化标志
         * @param qexclusive 排他队列标志
         * @param qauto_delete 自动删除标志
         * @param qargs 自定义参数键值对
         * @return 操作是否成功（队列已存在时返回true）
         * 
         * @note 线程安全操作，持久化队列会自动写入数据库
         */
        bool declareQueue(const std::string &qname, 
                        bool qdurable, 
                        bool qexclusive,
                        bool qauto_delete,
                        const google::protobuf::Map<std::string, std::string> &qargs) {
            std::unique_lock<std::mutex> lock(_mutex);
            
            if (_msg_queues.find(qname) != _msg_queues.end()) 
            {
                return true;
            }
            
            MsgQueue::ptr mqp = std::make_shared<MsgQueue>(
                qname, qdurable, qexclusive, qauto_delete, qargs);
            
            if (qdurable) 
            {
                if (!_mapper.insert(mqp)) return false;
            }
            
            _msg_queues.emplace(qname, mqp);
            return true;
        }
        
        /**
         * @brief 删除指定队列
         * @param name 要删除的队列名称
         * 
         * @note 线程安全操作，持久化队列会从数据库中移除
         */
        void deleteQueue(const std::string &name) 
        {
            std::unique_lock<std::mutex> lock(_mutex);
            auto it = _msg_queues.find(name);
            if (it == _msg_queues.end()) return;
            
            if (it->second->durable) 
            {
                _mapper.remove(name);
            }
            
            _msg_queues.erase(name);
        }
        
        /**
         * @brief 查询指定队列
         * @param name 要查询的队列名称
         * @return 队列智能指针（未找到返回nullptr）
         * 
         * @note 线程安全操作
         */
        MsgQueue::ptr selectQueue(const std::string &name) 
        {
            std::unique_lock<std::mutex> lock(_mutex);
            auto it = _msg_queues.find(name);
            return (it != _msg_queues.end()) ? it->second : nullptr;
        }
        
        /**
         * @brief 获取所有队列的副本
         * @return 队列映射的副本
         * 
         * @note 返回拷贝避免直接操作内部数据
         */
        QueueMap allQueues() 
        {
            std::unique_lock<std::mutex> lock(_mutex);
            return _msg_queues;
        }
        
        /**
         * @brief 检查队列是否存在
         * @param name 队列名称
         * @return 存在返回true，否则false
         */
        bool exists(const std::string &name) 
        {
            std::unique_lock<std::mutex> lock(_mutex);
            return _msg_queues.find(name) != _msg_queues.end();
        }
        
        /**
         * @brief 获取当前管理的队列数量
         * @return 队列数量
         */
        size_t size() 
        {
            std::unique_lock<std::mutex> lock(_mutex);
            return _msg_queues.size();
        }
        
        /**
         * @brief 清空所有队列（仅用于测试）
         * 
         * 删除数据库表并清空内存中的队列数据
         */
        void clear() 
        {
            _mapper.removeTable();
            _msg_queues.clear();
        }
        
    private:
        std::mutex _mutex;          ///< 线程互斥锁，保证操作原子性
        MsgQueueMapper _mapper;     ///< 持久化管理器实例
        QueueMap _msg_queues;       ///< 内存中的队列映射表
    };
}

#endif // __M_QUEUE_H__